import React, { Component, PropTypes } from 'react';
import {
  ListView,
  StyleSheet,
  Text,
  TextInput,
  View,
  Dimensions,
  Keyboard,
  ActivityIndicator,
} from 'react-native';

const WINDOW_HEIGHT = Dimensions.get('window').height;

class AutoComplete extends Component {
  static propTypes = {
    ...TextInput.propTypes,
    /**
     * These styles will be applied to the container which
     * surrounds the autocomplete component.
     */
    containerStyle: View.propTypes.style,
    /**
     * Assign an array of data objects which should be
     * rendered in respect to the entered text.
     */
    data: PropTypes.array,
    /*
     * These styles will be applied to the container which surrounds
     * the textInput component.
     */
    inputContainerStyle: View.propTypes.style,
    /**
     * These style will be applied to the result list view.
     */
    listStyle: ListView.propTypes.style,
    /**
     * `renderItem` will be called to render the data objects
     * which will be displayed in the result view below the
     * text input.
     */
    renderItem: PropTypes.func,
    /**
     * `onShowResults` will be called when list is going to
     * show/hide results.
     */
    onShowResults: PropTypes.func,

    searchData: PropTypes.array,
    searchListStyle: ListView.propTypes.style,
    renderSearchItem: PropTypes.func,
    onShowSearchResults: PropTypes.func,
  };

  static defaultProps = {
    data: [],
    searchData: [],
    defaultValue: '',
    renderItem: rowData => <Text>{rowData}</Text>,
    renderSearchItem: rowData => <Text>{rowData}</Text>
  };

  constructor(props) {
    super(props);
    const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => {return true;return r1 !== r2;} });
    const sds = new ListView.DataSource({ rowHasChanged: (r1, r2) => {return true;return r1 !== r2;} });
    this.state = {
      dataSource: ds.cloneWithRows(props.data),
      searchDataSource: sds.cloneWithRows(props.searchData),
      showResults: props.data && props.data.length > 0,
      showSearchResults: props.searchData && props.searchData.length > 0,
      listviewHeight: 0,
      isOverlayShow: false,
      isIndicatorShown: false,
      overlayWidth: 0,
      overlayHeight: 0,
    };
    this.keyboardHeight = 0;
    this.isOverlayShown = false;
    this.isKeyboardDismiss = false;
  }

  componentWillReceiveProps(nextProps) {
    // let dataSource = this.state.dataSource.cloneWithRows([]);
    // this.setState({ dataSource });
    const dataSource = this.state.dataSource.cloneWithRows(nextProps.data);
    const searchDataSource = this.state.searchDataSource.cloneWithRows(nextProps.searchData);
    const showResults = nextProps.data.length > 0;
    const showSearchResults = nextProps.searchData.length > 0;
    // this._showResults(dataSource.getRowCount() > 0);
    // this._showSearchResults(searchDataSource.getRowCount() > 0);
    this.setState({ dataSource, searchDataSource, showResults, showSearchResults });
  }

  componentDidMount() {
    this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', (frames) => {
      this.isKeyboardDismiss = false;
      if (!frames.endCoordinates) return;
          this.keyboardHeight = frames.endCoordinates.height;
          this.listviewView && this.listviewView.measure((ox, oy, width, height, px, py) => {
            this.setState({
              listviewHeight: WINDOW_HEIGHT - py - this.keyboardHeight - 10,
              overlayHeight: this.props.searchData.length > 0 ? WINDOW_HEIGHT - py - this.keyboardHeight - 10 : 0,
            })
          });
          // this.setState({
          //   listviewHeight: this.keyboardHeight,
          //   overlayHeight: this.props.searchData.length > 0 ? this.state.listviewHeight + this.keyboardHeight - 10 : 0,
          // });
    });

    this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', (frames) => {
      this.isKeyboardDismiss = true;
      this.listviewView && this.listviewView.measure((ox, oy, width, height, px, py) => {
        this.setState({
          listviewHeight: WINDOW_HEIGHT - py - 10,
          overlayHeight: this.props.searchData.length > 0 ? WINDOW_HEIGHT - py - 10 : 0,
        })
      });
      // if (this.keyboardHeight && this.keyboardHeight !== 0) {
      //   this.setState({
      //     listviewHeight: this.state.listviewHeight + this.keyboardHeight - 10,
      //     overlayHeight: this.props.searchData.length > 0 ? this.state.listviewHeight + this.keyboardHeight - 10 : 0,
      //   });
      // }
    });
  }
  
  componentWillUnmount() {
    this.keyboardDidShowListener.remove();
    this.keyboardDidHideListener.remove();
  }
  
  isOverlayShow(isShow) {
    // if (this.isOverlayShown === isShow) {
    //   return;
    // }

    this.isOverlayShown = isShow;
    if (isShow) {
      this.listviewView && this.listviewView.measure((ox, oy, width, height, px, py) => {
        this.setState({
          // overlayTop: -py,
          // overlayLeft: 0,
          overlayWidth: width,
          overlayHeight: height,
        })
      });
    }
    else {
      this.setState({
        // overlayTop: 0,
        // overlayLeft: 0,
        overlayWidth: 0,
        overlayHeight: 0,
      });
    }
  }

  /**
   * Proxy `blur()` to autocomplete's text input.
   */
  blur() {
    const { textInput } = this;
    textInput && textInput.blur();
  }

  /**
   * Proxy `focus()` to autocomplete's text input.
   */
  focus() {
    const { textInput } = this;
    textInput && textInput.focus();
  }

  _renderItems() {
    const { listStyle, renderItem } = this.props;
    const { dataSource } = this.state;
    return (
      <View style={{flex: 1, backgroundColor: 'rgba(100, 100, 100, 1)'}}>
      <Text style={{paddingTop: 8, paddingBottom: 8, justifyContent: 'center', alignSelf:'center', color: 'white',}}>已选收件人</Text>
      <ListView
        dataSource={dataSource}
        keyboardShouldPersistTaps={true}
        renderRow={renderItem}
        style={[styles.list, listStyle]}
      />
      </View>
    );
  }

  _renderSearchItems() {
    const {searchListStyle, renderSearchItem } = this.props;
    const { searchDataSource } = this.state;
    return (
      <View style={{flex: 1, backgroundColor: 'rgba(100, 100, 100, 1)'}}>
      <Text style={{paddingTop: 8, paddingBottom: 8, justifyContent: 'center', alignSelf:'center', color: 'white',}}>搜索结果</Text>
      <ListView
        dataSource={searchDataSource}
        keyboardShouldPersistTaps={true}
        renderRow={renderSearchItem}
        style={[styles.list, searchListStyle]}
      />
      </View>
    );
  }

  _showResults(show) {
    const { showResults } = this.state;
    const { onShowResults } = this.props;

    if (!showResults && show) {
      this.setState({ showResults: true });
      onShowResults && onShowResults(true);
    } else if (showResults && !show) {
      this.setState({ showResults: false });
      onShowResults && onShowResults(false);
    }
  }

  _showSearchResults(show) {
    const { showSearchResults } = this.state;
    const { onShowSearchResults } = this.props;

    if (!showSearchResults && show) {
      this.setState({ showSearchResults: true });
      onShowSearchResults && onShowSearchResults(true);
    } else if (showSearchResults && !show) {
      this.setState({ showSearchResults: false });
      onShowSearchResults && onShowSearchResults(false);
    }
  }

  setIndicatorShow(isIndicatorShown) {
    this.setState({ isIndicatorShown });
  }

  render() {
    const { showResults, showSearchResults } = this.state;
    const { containerStyle, inputContainerStyle, onEndEditing, style, ...props } = this.props;
    return (
      <View style={[styles.container, containerStyle]}>
        <View style={[styles.inputContainer, inputContainerStyle]}>
          <TextInput
            style={[styles.input, style]}
            ref={ref => (this.textInput = ref)}
            onEndEditing={e =>
              this._showResults(false) || (onEndEditing && onEndEditing(e))
            }
            {...props}
          />
        </View>
        <View ref={(ref) => {this.listviewView = ref}} style={[styles.listviewView, {backgroundColor: showResults?'white':'transparent',height: this.state.listviewHeight, borderWidth: showResults||showSearchResults?1:0,opacity:this.isOverlayShown||showResults?1:0,}]}>
          {showResults && this._renderItems()}
          <View style={{top: 0, left: 0, width: this.state.overlayWidth, height: this.state.listviewHeight, backgroundColor: '#00000055'}}>
            {
              this.state.isIndicatorShown ?
              <View style={styles.indicatorview}>
                  <ActivityIndicator animating={this.state.isIndicatorShown} style={styles.indicator} size={'large'} color={'white'} />
              </View>
              :
              (showSearchResults && this._renderSearchItems())
            }
            </View>
          </View>
      </View>
    );
  }
}

const border = {
  borderColor: '#b9b9b9',
  borderRadius: 1,
  borderWidth: 1
};

const styles = StyleSheet.create({
  container: {
    // flex: 1,
    // borderWidth: 1,
    // borderColor: 'yellow',
    // height: WINDOW_HEIGHT / 2,
    // backgroundColor: 'red',
  },
  inputContainer: {
    // ...border,
    // margin: 10,
    // marginBottom: 0
    // flex: 1,
    // paddingTop: 10,
    // paddingBottom: 10,
    height: 38,
    borderWidth: 1,
    borderColor: '#b9b9b9',
    borderRadius: 1,
    // borderColor: 'red',
  },
  input: {
    backgroundColor: 'white',
    height: 36,
  },
  list: {
    // ...border,
    backgroundColor: 'rgba(0, 0, 0, 0.05)',
    // borderTopWidth: 1,
    // borderBottomWidth: 1,
    // height: WINDOW_HEIGHT / 2.5,
    flex:1
    // top: 1,
    // left: 1,
    // borderWidth: 1,
    // borderColor: 'red',
    // margin: 10,
    // marginTop: 0
  },
  listviewView: {
    borderWidth: 1,
    borderColor: 'gray',  
    borderTopWidth: 0,
    backgroundColor: 'white',
  },
  indicatorview: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    // marginTop: -60,
  },
  indicator: {
    // height: 120,
    alignItems: 'center',
    justifyContent: 'center',
  },
});

export default AutoComplete;
